package com.spar.openprojects.client.composite;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.spar.openprojects.client.RemoteDataService;
import com.spar.openprojects.client.RemoteDataServiceAsync;
import com.spar.openprojects.shared.BusinessPartner;
import com.spar.openprojects.shared.Member;
import com.spar.openprojects.shared.Order;
import com.spar.openprojects.shared.OrderItem;
import com.spar.openprojects.shared.Project;

public class OrderComposite extends Composite {
	private RemoteDataServiceAsync asyncService = GWT
			.create(RemoteDataService.class);
	private Order order = new Order();

	private Member user = new Member();

	public Order getOrder() {
		return order;
	}

	public void setOrder(Order order) {
		this.order = order;
	}

	private Project project = new Project();
	private OrderItemComposite offerComposite;
	private OrderItemComposite orderComposite;
	private List<OrderItemComposite> billComposites = new ArrayList<OrderItemComposite>();

	private Label lblBusinessPartner = new Label("Business Partner");
	private ListBox listBoxBusinessPartners = new ListBox();
	private CheckBox chbEveryYear = new CheckBox();
	private List<BusinessPartner> businessPartners = new ArrayList<BusinessPartner>();

	private VerticalPanel vpBills = new VerticalPanel();
	private Button buttonExport = new Button("Export");
	private Button buttonAddBill = new Button("Add Bill");
	private Button buttonSave = new Button("Save");
	private Button buttonClose = new Button("Close");;

	public OrderComposite(Order order, Project project, final Member user) {
		this.order = order;
		this.project = project;
		this.user = user;

		DecoratorPanel decoratorPanel = new DecoratorPanel();
		initWidget(decoratorPanel);

		VerticalPanel verticalPanel = new VerticalPanel();
		decoratorPanel.setWidget(verticalPanel);
		HorizontalPanel horizontalPanel;

		HorizontalPanel horizontalPanel_1 = new HorizontalPanel();
		horizontalPanel_1.setSpacing(10);
		horizontalPanel_1
				.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		verticalPanel.add(horizontalPanel_1);
		verticalPanel.setCellHorizontalAlignment(horizontalPanel_1,
				HasHorizontalAlignment.ALIGN_RIGHT);
		horizontalPanel_1.setWidth("107px");
		horizontalPanel_1.add(buttonExport);
		horizontalPanel_1.add(buttonAddBill);
		horizontalPanel_1.add(buttonSave);
		buttonExport.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				exportOrder(true);
			}
		});
		verticalPanel.setCellHorizontalAlignment(buttonExport,
				HasHorizontalAlignment.ALIGN_RIGHT);
		buttonAddBill.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				saveOrder(true, user);
			}
		});
		verticalPanel.setCellHorizontalAlignment(buttonAddBill,
				HasHorizontalAlignment.ALIGN_RIGHT);
		buttonSave.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				saveOrder(false, user);
			}
		});
		verticalPanel.setCellHorizontalAlignment(buttonSave,
				HasHorizontalAlignment.ALIGN_RIGHT);
		horizontalPanel_1.add(buttonClose);

		buttonClose.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				Iterator<Widget> iterator = RootPanel.get(
						"openprojectsContainer").iterator();
				Widget widget;
				while (iterator.hasNext()) {
					widget = iterator.next();
					if (widget instanceof OrderComposite) {
						RootPanel.get("openprojectsContainer").remove(widget);
					}
				}
			}
		});
		buttonClose.setText("Close");
		horizontalPanel = new HorizontalPanel();
		verticalPanel.add(horizontalPanel);
		horizontalPanel.setWidth("1000px");

		HorizontalPanel horizontalPanel_2 = new HorizontalPanel();
		horizontalPanel_2.setSpacing(10);
		horizontalPanel.add(horizontalPanel_2);
		horizontalPanel_2.add(lblBusinessPartner);
		lblBusinessPartner.setWidth("100px");
		horizontalPanel_2.add(listBoxBusinessPartners);

		HorizontalPanel horizontalPanel_3 = new HorizontalPanel();
		horizontalPanel_3.setSpacing(10);
		horizontalPanel.add(horizontalPanel_3);

		Label lblEveryYear = new Label("Every Year");
		horizontalPanel_3.add(lblEveryYear);
		chbEveryYear.setValue(order.getEveryYear());
		horizontalPanel_3.add(chbEveryYear);

		HorizontalPanel horizontalPanelHeader = new HorizontalPanel();
		horizontalPanelHeader.setSpacing(10);

		Label labelAmount = new Label("Amount in \u20AC");
		labelAmount.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		Label labelNumber = new Label("Id/Number");
		Label labelLink = new Label("Folio Link");
		labelLink.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
		Label labelDate = new Label("Date");
		Label labelReleaseDate = new Label("Release Date");
		labelAmount.setWidth("200px");
		labelNumber.setWidth("200px");
		labelLink.setWidth("150px");
		labelDate.setWidth("150px");
		labelReleaseDate.setWidth("100px");

		horizontalPanelHeader.add(labelAmount);
		horizontalPanelHeader.add(labelNumber);
		horizontalPanelHeader.add(labelLink);
		horizontalPanelHeader.add(labelDate);
		horizontalPanelHeader.add(labelReleaseDate);
		verticalPanel.add(horizontalPanelHeader);
		horizontalPanelHeader.setWidth("450px");

		offerComposite = new OrderItemComposite(order.getOffer(), "Offer", user);

		orderComposite = new OrderItemComposite(order.getOrder(), "Order", user);

		verticalPanel.add(offerComposite);
		verticalPanel.add(orderComposite);

		updateBills();
		verticalPanel.add(vpBills);

		asyncService.getBusinessPartners(user,
				new AsyncCallback<List<BusinessPartner>>() {

					@Override
					public void onSuccess(List<BusinessPartner> businessPartners) {
						setBusinessPartners(businessPartners);
					}

					@Override
					public void onFailure(Throwable caught) {
						RootPanel.get("infoContainer").clear();
						RootPanel.get("infoContainer").add(
								new Label(caught.getMessage()));
					}
				});
	}

	protected void exportOrder(boolean b) {
		Window.open("http://" + Window.Location.getHost()
				+ "/openprojects/openprojects/orderingexcel?orderId="
				+ this.getOrder().getId(), "_blank", "");

	}

	protected void addBill() {
		this.getOrder().getBills().add(new OrderItem());
		this.updateBills();
	}

	public void updateBills() {
		billComposites.clear();
		for (OrderItem bill : order.getBills()) {
			billComposites.add(new OrderItemComposite(bill, "Bill", user));
		}
		vpBills.clear();
		for (OrderItemComposite billComposite : billComposites) {
			vpBills.add(billComposite);
		}
	}

	private void saveOrder(final Boolean addBill, final Member user) {
		order.setOffer(offerComposite.getOrderItem());
		order.setOrder(orderComposite.getOrderItem());
		List<OrderItem> bills = new ArrayList<OrderItem>();
		for (OrderItemComposite billComposite : billComposites) {
			bills.add(billComposite.getOrderItem());
		}
		order.setBills(bills);

		order.setBusinessPartner(businessPartners.get(listBoxBusinessPartners
				.getSelectedIndex()));
		order.setEveryYear(chbEveryYear.getValue());

		asyncService.persistOrder(order, user, new AsyncCallback<Order>() {

			@Override
			public void onSuccess(Order resultOrder) {
				RootPanel.get("infoContainer").clear();
				RootPanel.get("infoContainer").add(
						new Label("Order saved (id:" + resultOrder.getId()
								+ ") for project " + project.getDescription()
								+ "(" + project.getNumber() + ")"));
				order = resultOrder;
				Iterator<Widget> iterator = RootPanel.get(
						"openprojectsContainer").iterator();
				Widget widget;
				while (iterator.hasNext()) {
					widget = iterator.next();
					if (widget instanceof ProjectsComposite) {
						((ProjectsComposite) widget).loadProjects(true,
								project, user);
					}
					if (widget instanceof OrderComposite && !addBill) {
						RootPanel.get("openprojectsContainer").remove(widget);
					}
				}
				if (addBill)
					addBill();
			}

			@Override
			public void onFailure(Throwable caught) {
				RootPanel.get("infoContainer").clear();
				RootPanel.get("infoContainer").add(
						new Label(caught.getMessage()));
			}
		});

	}

	private void setBusinessPartners(List<BusinessPartner> businessPartners) {
		this.businessPartners = businessPartners;
		int index = 0;
		for (BusinessPartner businessPartner : businessPartners) {
			listBoxBusinessPartners.addItem(businessPartner.getName());
			if (businessPartner.getId().equals(
					order.getBusinessPartner().getId())) {
				index = businessPartners.indexOf(businessPartner);
			}
		}
		listBoxBusinessPartners.setItemSelected(index, true);

	}
}
